package com.zhengx.wifip2phelper

import android.Manifest
import android.content.Context
import android.content.IntentFilter
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.net.wifi.p2p.*
import android.os.Handler
import android.support.annotation.RequiresPermission
import android.util.Log
import kotlin.collections.ArrayList

/**
 * wifi p2p扫描连接操作封装
 * Created by zhengx on 2018/11/8
 */
open class WifiP2PHelper(private val context: Context,
                    private val wifiStatusChangeListener: WifiStatusChangeListener,
                         var discoverListener: DiscoverListener) :
        WifiP2pManager.PeerListListener {

    private val TAG = javaClass.simpleName

    private val isDebug = true

    private val timeoutHandler = Handler()

    private val scanTimeoutRunnable = Runnable {
        stopDiscovery()
    }

    private val wifiP2pManager :WifiP2pManager = context.applicationContext
            .getSystemService(Context.WIFI_P2P_SERVICE) as WifiP2pManager

    private val channel: WifiP2pManager.Channel

    val deviceList: ArrayList<WifiP2pDevice> = ArrayList()

    /*当前mac地址*/
    private var currentMAC: String? = null

    var connectedDevice: WifiP2pDevice ?= null

    private var isBroadcastRegistered = false

    private val wifiP2PBroadcastReceiver: WifiP2PBroadcastReceiver = WifiP2PBroadcastReceiver()

    /**
     * 初始化
     * */
    init {
        channel = wifiP2pManager.initialize(context, context.mainLooper, null)
        if (channel == null)
            debug("wifi p2p init failed! channel is null")

        this.wifiP2PBroadcastReceiver.wifiStatusChangeListener = wifiStatusChangeListener
    }

    /**
     * 当前设备信息
     * */
    fun getThisDevice() :WifiP2pDevice? {
        return wifiP2PBroadcastReceiver.thizDevice
    }

    /**
     * 判断wifi是否打开
     * */
    fun isWifiOn() :Boolean {
        val wifiManager = context.applicationContext
                .getSystemService(Context.WIFI_SERVICE) as WifiManager

        return wifiManager.isWifiEnabled
    }

    /**
     * WiFi p2p直连是否可用
     * */
    fun isWifiP2pEnable() : Boolean {
        return wifiP2PBroadcastReceiver.isWifiP2pEnable
    }
    /**
     * 是否在扫描中
     * */

    fun isScnning(): Boolean {
        return wifiP2PBroadcastReceiver.isScanning
    }

    /**
     * 当前连接状态：是否连接
     * */
    fun isConnected() : Boolean {
        return wifiP2PBroadcastReceiver.isConnectedDevice
    }

    /**
     * 当前连接状态：networkinfo
     * */
    fun getCurrentNetworkInfo(): NetworkInfo? {
        return wifiP2PBroadcastReceiver.currentNetworkInfo
    }

    /**
     * 当前连接状态：wifip2pInfo
     * */
    fun getCurrentWifiP2pInfo(): WifiP2pInfo? {
        return wifiP2PBroadcastReceiver.currentWifiP2pInfo
    }

    /**
     * 当前连接状态：wifip2pgroup
     * */
    fun getCurrentWifip2pGroup(): WifiP2pGroup? {
        return wifiP2PBroadcastReceiver.currentWifiP2pGroup
    }
    /**
     * 更新wifi信息
     * */
    @RequiresPermission(Manifest.permission.ACCESS_WIFI_STATE)
    private fun getWifiMac() {
        val wifiManager = context.applicationContext
                .getSystemService(Context.WIFI_SERVICE) as WifiManager
        currentMAC = if (wifiManager.connectionInfo == null) null else wifiManager.connectionInfo.macAddress
    }


    /**
     * 打开/关闭wifi
     * */
    @RequiresPermission(Manifest.permission.CHANGE_WIFI_STATE)
    fun toggleWifi(isOpen: Boolean) {
        val wifiManager = context.applicationContext
                .getSystemService(Context.WIFI_SERVICE) as WifiManager
        wifiManager.isWifiEnabled = isOpen
    }

    /**
    * 设置扫描超时时间
    * */
    fun discoverDevice(timeout: Long): Boolean {
        if (!isWifiOn() || !isWifiP2pEnable()) {
            return false
        }
        if (timeout > 0) {
            timeoutHandler.removeCallbacks(scanTimeoutRunnable)
            timeoutHandler.postDelayed(scanTimeoutRunnable, timeout)
        }
        return discoverDevice()
    }
    /**
     * 开始查找设备
     * 开始查找wifi设备
     * @return
     */
    fun discoverDevice(): Boolean {

        if (!isWifiOn() || !isWifiP2pEnable()) {
            return false
        }
        //开始发现设备，这里回调状态
        debug("WifiP2pHelper-->discoverDevice()")
        wifiP2pManager.discoverPeers(channel, object : WifiP2pManager.ActionListener {
            override fun onSuccess() {
                debug("wifi discoverDevice()调用 success")
                //discovery peer success
                discoverListener.onDiscoverStart(true, 0)
            }

            override fun onFailure(reasonCode: Int) {
                debug("wifi discoverDevice()调用 failed，错误码：$reasonCode")
                //failed
                discoverListener.onDiscoverStart(false, reasonCode)
            }
        })
        return true
    }

    /**
     * 停止查找设备
     * 停止查找wifi设备
     * @return
     */
    fun stopDiscovery() :Boolean {
        if (!isWifiOn()) {
            return false
        }
        debug("WifiP2pHelper-->stopPeerDiscovery()")

        wifiP2pManager.stopPeerDiscovery(channel, object : WifiP2pManager.ActionListener {
            override fun onSuccess() {
                debug("wifi stopPeerDiscovery()调用 success")
                discoverListener.onStopDiscovery(true, 0)
            }

            override fun onFailure(reason: Int) {
                debug("wifi stopPeerDiscovery()调用 failed, 错误码:$reason")
                discoverListener.onStopDiscovery(false, reason)
            }
        })
        return true
    }

    /**
     * 刷新wifi p2p设备列表
     * */
    fun requestPeers() {
        wifiP2pManager.requestPeers(channel, this)
    }

    /**
     * 断开WiFi直连，如果有连接的话
    * */
    fun disConnectDevice(actionListener: WifiP2pManager.ActionListener) {
        if (isConnected()) {
            wifiP2pManager.cancelConnect(channel, actionListener)
        }
    }

    /**
     * 连接到设备
     * @param device
     * @param listener
     */
    fun connectDevice(device: WifiP2pDevice) {
        debug("WifiP2pHelper-->connectDevice()")
        val config = WifiP2pConfig()
        config.deviceAddress = device.deviceAddress

        wifiP2pManager.connect(channel, config, object : WifiP2pManager.ActionListener {
            override fun onSuccess() {
                wifiStatusChangeListener.onConnectResult(true)
                connectedDevice = device
            }

            override fun onFailure(reason: Int) {
                wifiStatusChangeListener.onConnectResult(false)
                connectedDevice = null
            }
        })
    }

    /**
     * 注册wifi P2p广播
     * */
    fun registerWifiBroadcast() {
        if (!isBroadcastRegistered) {
            val intentFilter = IntentFilter()
            intentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION)
            intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION)
            intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION)
            intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)
            intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION)
            intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
            context.registerReceiver(wifiP2PBroadcastReceiver, intentFilter)
            isBroadcastRegistered = true
        }
    }

    /**
    * 取消wifi p2p广播
    * */
    fun unRegisterWifiBroadcast() {
        if (isBroadcastRegistered) {
            context.unregisterReceiver(wifiP2PBroadcastReceiver)
            isBroadcastRegistered = false
        }
    }

    /*=================================wifi p2p broadcast callback=================================================*/

    override fun onPeersAvailable(peers: WifiP2pDeviceList?) {
//        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
        deviceList.clear()
        deviceList.addAll(peers?.deviceList ?: ArrayList<WifiP2pDevice>())
        wifiStatusChangeListener.onUpdatePeers(deviceList)
    }

    private fun debug(value: String) {
        if (isDebug) {
            Log.d(TAG, value)
        }
    }

}
